package edu.washington.ling.syntric.consistency;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import edu.washington.ling.syntric.struct.tree.Token;
import edu.washington.ling.syntric.struct.tree.Tree;


public class RelationMappingRule extends ConsistencyRule {
	private Map<String, String> contextFreeMap;
	private Set<String> beVerbSet;
	
	public RelationMappingRule() throws IOException {
		loadMapping();
		loadBeVerbs();
	}
	private void loadMapping() throws IOException {
		contextFreeMap = new HashMap<String, String>();
		File mappingFile = new File("resources", "mapping.txt");
		InputStream is = this.getClass().getResourceAsStream(mappingFile.getPath());
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String line = null;
		while ((line = br.readLine()) != null) {
			String[] entry = line.split("\\s");
			if (entry.length == 2) {
				contextFreeMap.put(entry[0], entry[1]);
			}
		}
	}
	private void loadBeVerbs() throws IOException {
		beVerbSet = new HashSet<String>();
		File beVerbFile = new File("resources", "be-verbs.txt");
		InputStream is = this.getClass().getResourceAsStream(beVerbFile.getPath());
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String line = null;
		while ((line = br.readLine()) != null) {
			beVerbSet.add(line);
		}
	}
	public void apply(Tree ds) {
		Token dsRoot = ds.getDSRoot();
		apply(dsRoot, ds);
	}
	
	private void applyContextFreeMapping(Token t) {
		for (Token child: t.getDSDependents()) {
			String relType = child.getDSRelation();
			// Trigger
			if (contextFreeMap.containsKey(relType)) {
				// Response
				child.setDSRelation(contextFreeMap.get(relType));
			}
		}
		
	}
	
	private void applyk2gTok2sMapping(Token t) {
		Token k2sChild = null, k2gChild = null;
		for (Token child: t.getDSDependents()) {
			if (child.getDSRelation().equals("k2g")) {
				k2gChild = child;
			}
			if (child.getDSRelation().equals("k2s")) {
				k2sChild = child;
			}
		}
		// Trigger
		if (k2gChild != null && k2sChild == null) {
			// Response
			k2gChild.setDSRelation("k2s");
		}
	}
	
	private void applyk7pTok2sMapping(Token t, Tree ds) {
		Token k7pChild = null, k2sChild = null, k1Child = null;
		for (Token child: t.getDSDependents()) {
			if (child.getDSRelation().equals("k7p")) {
				k7pChild = child;
			}
			if (child.getDSRelation().equals("k2s")) {
				k2sChild = child;
			}
			if (child.getDSRelation().equals("k1")) {
				k1Child = child;
			}
		}
		// Trigger (pt 1)
		if (beVerbSet.contains(t.getWord()) && k7pChild != null && k1Child != null && k2sChild == null) {
			// Trigger (pt 2)
			if (ds.getTokenPosition(k1Child) < ds.getTokenPosition(k7pChild)) {
				// Response
				k7pChild.setDSRelation("k2s");
			}
		}
	}
	
	public void apply(Token t, Tree ds) {
		for (Token child: t.getDSDependents()) {
			apply(child, ds);
		}
		applyContextFreeMapping(t);
		applyk2gTok2sMapping(t);
		applyk7pTok2sMapping(t, ds);
	}
}
